<script>
import {defineAsyncComponent} from "vue";

// 异步组件哈希表
let asyncComponentMap = {}
// 组件异步导入promise对象哈希表
let promiseComponentMap = {}

// 获取所有param组件的导入方法
let import_vue_function_map = import.meta.glob('./param/*.vue');
Object.keys(import_vue_function_map).forEach(path=>{
  let view_key = path.replace(/^.*?\/([^\/]+)\.vue$/,'$1');
  if (~['_'].indexOf(view_key)) return; // 不导入的组件
  asyncComponentMap[view_key] = defineAsyncComponent(import_vue_function_map[path]);
  promiseComponentMap[view_key] = import_vue_function_map[path]();
})

/**获取参数组件的配置哈希表
 * @returns {Promise<{[componentName: string]:{name,其他_包裹的属性}}>}
 */
export async function getParamConfigMap(){
  if (getParamConfigMap._cache_) return getParamConfigMap._cache_;
  let list = await Promise.all(Object.values(promiseComponentMap));
  let ks = Object.keys(promiseComponentMap);

  let config = {}
  list.forEach((module,i)=>{
    let k = ks[i];
    let component = module.default;
    let config_row = {name: k}
    // 提取组件定义的 _配置名_ 参数作为config
    Object.keys(component).forEach(k2 => {
      let ms = k2.match(/^_(.+)_$/);
      if (ms) config_row[ms[1]] = component[k2];
    })
    config[k] = config_row;
  })

  getParamConfigMap._cache_ = config;
  return config;
}

console.log(asyncComponentMap);
export default {
  _tip_: '所有表单参数组件归一化中间件',
  components: asyncComponentMap,
  props: {
    component: String, // 参数组件名称，如果组件不存在，会把值作为HTML渲染
    name: {type:String, default:''}, // form表单的name
    modelValue: {type:[String,Number,Object,Array], default:''}, // 值
  },
  emits: ['update:modelValue', 'validate'],
  computed: {
    isComponents(){
      return this.component in this.$options.components;
    }
  },
  mounted(){

  }
}
</script>

<template>
  <component
    v-if="isComponents"
    :is="component"
    :name="name"
    :modelValue="modelValue"
    @update:modelValue="$emit('update:modelValue', $event)"
    v-bind="$attrs"
  />
  <div v-else v-html="modelValue"></div>
</template>

<style scoped lang="scss">

</style>